/************************************************************************

								Heroes IV
					  Copyright 2000, The 3DO Company

	------------------------------------------------------------------
  						 metatile_texture.cpp

	$Header: /heroes4/metatile_texture.cpp $

	$NoKeywords: $

 ************************************************************************/

// kill the 255+ character identifier warning.  Templates tend to exceed that easily.
#include "precompiled.h"
#pragma warning( disable: 4786 )

#include "metatile_texture.h"

#include <algorithm>

#include "convert_16_bit.h"
#include "streambuf_operators.h"

char const t_resource_traits<t_metatile_texture_24>::prefix[] = "terrain";

char const t_resource_traits<t_metatile_texture_24>::extension[] = "psd";

/////////////////////////////////////////////////////////////////////////////
t_adventure_tile_texture::t_adventure_tile_texture( std::vector< t_uint8 > & data, int const ( & column_offset_array )[ k_adventure_tile_width ] )
{
	set_data( data, column_offset_array );
}

/////////////////////////////////////////////////////////////////////////////
// single adventure tile texture
/////////////////////////////////////////////////////////////////////////////
bool t_adventure_tile_texture::read( std::streambuf & buffer )
{
	std::vector< t_uint8 > new_data;
	int new_column_offset_array[ k_adventure_tile_width ];

	try
	{
		int data_size = get< t_uint32 >( buffer );

		new_data.resize( data_size );
		if ( ::read( buffer, &new_data[ 0 ], data_size ) != data_size )
			return false;

		int i;
		for ( i = 0; i < k_adventure_tile_width; ++i )
			new_column_offset_array[ i ] = get< t_uint32 >( buffer );
	}
	catch ( t_streambuf_read_failure const & )
	{
		return false;
	}

	new_data.swap( m_data );
	std::copy( &new_column_offset_array[ 0 ], &new_column_offset_array[ k_adventure_tile_width ], &m_column_offset_array[ 0 ] );
	
	return true;
}

/////////////////////////////////////////////////////////////////////////////
// single adventure tile texture
/////////////////////////////////////////////////////////////////////////////
bool t_adventure_tile_texture::write( std::streambuf & buffer ) const
{
	try
	{
		put< t_uint32 >( buffer, m_data.size() );

		if ( ::write( buffer, &m_data[ 0 ], m_data.size() ) != m_data.size() )
			return false;

		int i;
		for ( i = 0; i < k_adventure_tile_width; ++i )
			put< t_uint32 >( buffer, m_column_offset_array[ i ] );
	}
	catch ( t_streambuf_write_failure const & )
	{
		return false;
	}

	return true;
}

/////////////////////////////////////////////////////////////////////////////
// single adventure tile texture
/////////////////////////////////////////////////////////////////////////////
void t_adventure_tile_texture::set_data( std::vector< t_uint8 > & new_data, int const ( & new_column_offset_array )[ k_adventure_tile_width ] )
{
	new_data.swap( m_data );
	std::copy( &new_column_offset_array[ 0 ], &new_column_offset_array[ k_adventure_tile_width ], &m_column_offset_array[ 0 ] );
}

/////////////////////////////////////////////////////////////////////////////
// t_metatile_texture24 class - 24 bit paletted terrain tile
/////////////////////////////////////////////////////////////////////////////
bool t_metatile_texture_24::read( std::streambuf& buffer )
{
	int i;
	int palette_size;

	for (i = 0; i < ELEMENTS_OF( m_tile_texture_arr ); i++)
		if (!m_tile_texture_arr[i].read( buffer ))
			return false;

	buffer >> palette_size;
	m_palette.resize( palette_size );
	if (::read( buffer, &(*m_palette.begin()), palette_size * sizeof(t_pixel_24) ) 
		!= palette_size * sizeof(t_pixel_24))
		return false;
	return true;
}

/////////////////////////////////////////////////////////////////////////////
// t_metatile_texture24 class - 24 bit paletted terrain tile
/////////////////////////////////////////////////////////////////////////////
bool t_metatile_texture_24::write( std::streambuf& buffer ) const
{
	int i;

	for (i = 0; i < ELEMENTS_OF( m_tile_texture_arr ); i++)
		if (!m_tile_texture_arr[i].write( buffer ))
			return false;

	buffer << m_palette.size();
	if (::write( buffer, &(*m_palette.begin()), m_palette.size() * sizeof(t_pixel_24) ) 
		!= m_palette.size() * sizeof(t_pixel_24))
		return false;
	return true;
}

/////////////////////////////////////////////////////////////////////////////
// t_metatile_texture class - 16 bit paletted terrain tile
/////////////////////////////////////////////////////////////////////////////

t_metatile_texture::t_metatile_texture( t_metatile_texture_24 const & source_tile )
{
	copy_data( source_tile );
	// convert the palette to 16 bit.

	std::vector<t_pixel_24> const& palette = source_tile.get_palette();
	std::vector<t_pixel_24>::const_iterator index;
	std::vector<t_uint16>::iterator dest;

	m_palette.resize( palette.size() );
	index = palette.begin();
	dest = m_palette.begin();
	while (index != palette.end())
		*dest++ = convert_to_16_bit( *index++ );
}

